﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using App1AppHandler;
using System.Timers;
using Reborn_WorldServer;

namespace Reborn_Server.App1AppHandler
{
    public class TargetAreaSpell : TargetSpell
    {
        //List of map items effected by this area spell, this will get set by the subclass when it casts
        protected volatile List<MapItem> MapItems = new List<MapItem>();

        //Map info for list of map items
        protected int MapID = -1;
        protected int Instance = -1;

        //Timer used to turn off the area effect (Client is not smart enough yet)
        protected Timer spellTimer = new Timer(1500);

        public TargetAreaSpell() : base() 
        {
            spellTimer.AutoReset = false;
            spellTimer.Elapsed += new ElapsedEventHandler(SpellTimer_Expired);
        }

        protected override bool InitializeInstantCast(CreatureBase myCreatureBase, CreatureBase _targetCreatureBase, SpellIcon sIcon, int CastLevel, bool sendMessages)
        {
            if (base.InitializeInstantCast(myCreatureBase, _targetCreatureBase, sIcon, CastLevel, sendMessages) == false)
                return false;

            MapID = _targetCreatureBase.MapID;
            Instance = _targetCreatureBase.Instance;

            spellTimer.Start();

            return true;
        }

        //Called by subclass to initialize the spell
        protected override bool InitializeCast(CreatureBase myCreatureBase, int CastLevel, long CreatureGUID, bool sendMessages, out List<MapItem> MapItemsWithin12)
        {
            if (base.InitializeCast(myCreatureBase, CastLevel, CreatureGUID, sendMessages, out MapItemsWithin12) == false)
                return false;

            MapID = myCreatureBase.MapID;
            Instance = myCreatureBase.Instance;

            spellTimer.Start();

            return true;
        }

        //Target area spells do not persist on the field so removing them is simply
        //To get rid of the effect, we do not need to worry about modifying anything 
        private void SpellTimer_Expired(object source, ElapsedEventArgs e)
        {
            LockItem lockItem = Managers.GameHandler.GetLockItem(MapID, Instance);

            lock (lockItem.LockObj)
            {
                //Get Map
                Map CurrentMap = Managers.GameHandler.GetMap(MapID, Instance);
                List<Character> CharsToUpdate = new List<Character>();

                bool foundSpell = false;
                foreach (MapItem mapitem in MapItems)
                {
                    foreach (Spell spell in mapitem.SpellLayer0)
                    {
                        if (spell.SpellID == this.SpellID)
                        {
                            foundSpell = true;
                            mapitem.SpellLayer0.Remove(this);
                            break;
                        }
                    }
                    foreach (Spell spell in mapitem.SpellLayer1)
                    {
                        if (spell.SpellID == this.SpellID)
                        {
                            foundSpell = true;
                            mapitem.SpellLayer1.Remove(this);
                            break;
                        }
                    }
                }
                
                if (foundSpell == true)
                {
                    foreach (MapItem mapitem in CurrentMap.MapItems)
                    {
                        if (Math.Abs(mapitem.MapX - MapItems[0].MapX) <= 4 && Math.Abs(mapitem.MapY - MapItems[0].MapY) <= 4)
                        {
                            foreach (CreatureBase creaturebase in mapitem.CreaturesBases)
                            {
                                if (creaturebase is Character)
                                    CharsToUpdate.Add((Character)creaturebase);
                            }
                        }
                    }
                }
                if (CharsToUpdate.Count > 0)
                {
                    foreach (Character character in CharsToUpdate)
                    {
                        character.AddMapItem(MapItems[0]);
                    }
                }
            }
        }
    }
}
